using System;
using System.Collections;
using System.Diagnostics;

namespace Common
{
	/// <summary>
	/// Trace class for easy access to Trace methods
	/// To use this functionality you can add a app.config file in the project directory
	/// </summary>
	public class Trace
	{
		/// <summary>
		/// Log error and throw an exception
		/// </summary>
		/// <param name="exception">Exception to throw</param>
		public static void Throw(System.Exception exception) {
			Trace.Error(exception.ToString());
			throw exception;
		}

        /// <summary>
        /// Log error
        /// </summary>
        /// <param name="s">Error message</param>
        public static void Error(string s) {
            if (generalSwitch_m.TraceError) {
                System.Diagnostics.Trace.WriteLine(DateTime.Now.ToString() + ":" + s);
                System.Diagnostics.Trace.Flush();
            }
        }
        
        /// <summary>
        /// Log warning
        /// </summary>
        /// <param name="s">Warning message</param>
        public static void Warning(string s) {
            if (generalSwitch_m.TraceWarning) {
                System.Diagnostics.Trace.WriteLine(DateTime.Now.ToString() + ":" + s);
                System.Diagnostics.Trace.Flush();
            }
        }
        
        /// <summary>
        /// Log information
        /// </summary>
        /// <param name="s">Information string</param>
        public static void Info(string s) {
            if (generalSwitch_m.TraceInfo) {
                System.Diagnostics.Trace.WriteLine(DateTime.Now.ToString() + ":" + s);
                System.Diagnostics.Trace.Flush();
            }
        }
        /// <summary>
        /// Log information with switch
        /// </summary>
        /// <param name="s">Information string</param>
        /// <param name="c">Switch</param>
        public static void Info(string s, string c) {
            if (CheckSwitch(c).TraceInfo) {
                System.Diagnostics.Trace.WriteLine(DateTime.Now.ToString() + ":" + s, c);
                System.Diagnostics.Trace.Flush();
            }
        }

        /// <summary>
        /// Log verbose
        /// </summary>
        /// <param name="s">Verbose string</param>
        public static void Verbose(string s) {
            if (generalSwitch_m.TraceVerbose) {
                System.Diagnostics.Trace.WriteLine(DateTime.Now.ToString() + ":" + s);
                System.Diagnostics.Trace.Flush();
            }
        }
        /// <summary>
        /// Log verbose with string
        /// </summary>
        /// <param name="s">Verbose string</param>
        /// <param name="c">Switch</param>
        public static void Verbose(string s, string c) {
            if (CheckSwitch(c).TraceVerbose) {
                System.Diagnostics.Trace.WriteLine(DateTime.Now.ToString() + ":" + s, c);
                System.Diagnostics.Trace.Flush();
            }
        }

        /// <summary>
        /// Find correct switch
        /// </summary>
        /// <param name="c">Switch to find</param>
        /// <returns>Trace switch</returns>
        private static TraceSwitch CheckSwitch(string c) {
            TraceSwitch s = null;
            if (switches_m.Contains(c)) {
                s = (TraceSwitch) switches_m[c];
            } else {
                // Create switch
                s = new TraceSwitch(c, c);
                switches_m.Add(c, s);
            }

            return s;
        }

        /// <summary>
        /// General Trace Switch
        /// </summary>
        private static TraceSwitch generalSwitch_m = new TraceSwitch("General", "Whole application");
        
        /// <summary>
        /// Table of all switches
        /// </summary>
        private static Hashtable switches_m = new Hashtable();
	}
}
